﻿using System.Collections.Generic;
using System.Xml;
using Jayden.Dll.Core.Persistence;
using Jayden.Dll.Core.Persistence.Models;
using Jayden.Dll.Core.Persistence.Xml;

namespace Jayden.Dll.Core.Membership
{
	public class XmlUserRoleDataAccess : XmlDataAccess<UserRole>, UserRoleDataAccess
	{
		public XmlUserRoleDataAccess(Configuration config, UnitOfWork uow, Entity entity) : base(config, uow, entity) { }

		public UserRole Read(string username, string rolename) { return Read(UnitOfWork.NewObjectId(Entity, username, rolename)); }

		public UserRole Create(string username, string rolename)
		{
			UserRole newUserRole = new UserRole(UnitOfWork);
			newUserRole.UserName = username;
			newUserRole.RoleName = rolename;
			Create(newUserRole);
			return newUserRole;
		}

		private string m_XPathRoleName = null;
		protected string XPathRoleName(string rolename)
		{
			if (m_XPathRoleName == null)
				m_XPathRoleName = XmlHelper.XPath(Entity, Entity["RoleName"]);
			return string.Format(m_XPathRoleName, rolename);
		}

		private string m_XPathUserName = null;
		protected string XPathUserName(string username)
		{
			if (m_XPathUserName == null)
				m_XPathUserName = XmlHelper.XPath(Entity, Entity["UserName"]);
			return string.Format(m_XPathUserName, username);
		}

		private string m_XPathUserNameRoleName = null;
		protected string XPathUserNameRoleName(string username, string roleName)
		{
			if (m_XPathUserNameRoleName == null)
				m_XPathUserNameRoleName = XmlHelper.XPath(Entity, Entity["UserName"], Entity["RoleName"]);
			return string.Format(m_XPathUserNameRoleName, username, roleName);
		}

		public void DeleteByUserName(string username)
		{
			string xpath = XPathUserName(username);
			using (XmlNodeProxy root = GetRoot(true))
			{
				XmlNodeList nodes = root.Node.SelectNodes(xpath);
				if (nodes == null || nodes.Count == 0)
					return;
				foreach(XmlNode node in nodes)
					node.ParentNode.RemoveChild(node);
			}
		}

		public void DeleteByRoleName(string rolename)
		{
			string xpath = XPathRoleName(rolename);
			using (XmlNodeProxy root = GetRoot(true))
			{
				XmlNodeList nodes = root.Node.SelectNodes(xpath);
				if (nodes == null || nodes.Count == 0)
					return;
				foreach (XmlNode node in nodes)
					node.ParentNode.RemoveChild(node);
			}
		}

		public List<UserRole> FindByUserName(string username)
		{
			string xpath = XPathUserName(username);
			using (XmlNodeProxy root = GetRoot(true))
			{
				List<UserRole> roles = new List<UserRole>();
				XmlNodeList nodes = root.Node.SelectNodes(xpath);
				if (nodes == null || nodes.Count == 0)
					return roles;
				foreach (XmlNode node in nodes)
					roles.Add(CreateFromXmlElement(node as XmlElement));
				return roles;
			}
		}

		public List<UserRole> FindByRoleName(string rolename)
		{
			string xpath = XPathRoleName(rolename);
			using (XmlNodeProxy root = GetRoot(true))
			{
				List<UserRole> roles = new List<UserRole>();
				XmlNodeList nodes = root.Node.SelectNodes(xpath);
				if (nodes == null || nodes.Count == 0)
					return roles;
				foreach (XmlNode node in nodes)
					roles.Add(CreateFromXmlElement(node as XmlElement));
				return roles;
			}
		}


		public void Delete(string username, string rolename) { Delete(UnitOfWork.NewObjectId(Entity, username, rolename)); }


		public List<UserRole> FindByRoleName(string rolename, string usernameLike)
		{
			string xpath = XPathRoleName(rolename);
			using (XmlNodeProxy root = GetRoot(true))
			{
				List<UserRole> roles = new List<UserRole>();
				XmlNodeList nodes = root.Node.SelectNodes(xpath);
				if (nodes == null || nodes.Count == 0)
					return roles;
				foreach (XmlNode node in nodes)
					if (node is XmlElement && node.Name == Entity.Table.TableName)
					{
						XmlAttribute attribute = node.Attributes["UserName"];
						if (attribute != null && attribute.Value.Contains(usernameLike))
							roles.Add(CreateFromXmlElement(node as XmlElement));
					}
				return roles;
			}
		}
	}
}
